package base

import "jvmgo/ch05/rtda"

//定义了指令接口
type Instruction interface {
	FetchOperands(reader *BytecodeReader) //从字节码中提取操作数
	Execute(frame *rtda.Frame)            //执行指令逻辑
}

/*
	下面的一些结构，相当于是上面指令接口的一些抽象实现，相当于抽象类
	这些抽象结构主要是实现FetchOperands方法，因为好多指令的操作数是类似的。
	所以一些具体的指令在实现上面的接口时，可以选择合适的结构继承，并只专注于Execute方法的实现。
*/

/*
	没有操作数的指令，FetchOperands方法什么也不需要干
*/
type NoOperandsInstruction struct {
	// empty
}

func (self *NoOperandsInstruction) FetchOperands(reader *BytecodeReader) {
	// nothing to do
}

/*
	表示跳转指令，offset存放跳转偏移量
*/
type BranchInstruction struct {
	Offset int
}

func (self *BranchInstruction) FetchOperands(reader *BytecodeReader) {
	self.Offset = int(reader.ReadInt16())
}

/*
	存储和加载类指令需要根据索引来存取局部变量表，索引的值由单字节操作数给出
	把这些指令抽象成Index8Instruction
	Index表示布局变量表的索引
*/
type Index8Instruction struct {
	Index uint
}

func (self *Index8Instruction) FetchOperands(reader *BytecodeReader) {
	self.Index = uint(reader.ReadUint8())
}

/*
	有一些指令需要访问运行时常量池，常量池索引由两字节操
	作数给出。把这类指令抽象成Index16Instruction结构体，用Index字
	段表示常量池索引
*/
type Index16Instruction struct {
	Index uint
}

func (self *Index16Instruction) FetchOperands(reader *BytecodeReader) {
	self.Index = uint(reader.ReadUint16())
}
